package com.yanfan.iot.tdengine.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.taosdata.jdbc.TSDBDriver;
import com.yanfan.common.utils.StringUtils;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

/**
 * 类名: TDengineConfig
 * 描述: TDengine配置类
 * 时间: 2022/5/13,0016 1:14
 * 开发人: wxy
 */
@Slf4j
@Configuration
@MapperScan(basePackages = {"com.yanfan.*.tdengine"}, sqlSessionTemplateRef = "tdengineSqlSessionTemplate", sqlSessionFactoryRef = "tDengineSqlSessionFactory")
@ConditionalOnProperty(name = "spring.datasource.druid.tdengine-server.enabled", havingValue = "true")
public class TDengineConfig {

    @Getter
    @Value("${spring.datasource.druid.tdengine-server.dbName}")
    private String dbName;
    @Value("${spring.datasource.druid.tdengine-server.url}")
    private String jdbc;
    @Value("${spring.datasource.druid.tdengine-server.username}")
    private String username;
    @Value("${spring.datasource.druid.tdengine-server.password}")
    private String password;
    @Value("${spring.datasource.druid.tdengine-server.precision:ns}")
    private String precision;
    @Value("${spring.datasource.druid.tdengine-server.keep:3650}")
    private Integer keep;
    @Value("${spring.datasource.druid.tdengine-server.duration:1}")
    private Integer duration;
    @Value("${spring.datasource.druid.tdengine-server.buffer:32}")
    private Integer buffer;

    @Bean(name = "tDengineDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.druid.tdengine-server")
    public DataSource tdengineDataSource() {
        return new DruidDataSource();
    }


    @Bean(name = "tDengineSqlSessionFactory")
    public SqlSessionFactory tDengineSqlSessionFactory(@Qualifier("tDengineDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setMapperLocations(resolveMapperLocations(StringUtils.split("classpath*:mapper/tdengine/*.xml", ",")));
        sqlSessionFactoryBean.setDataSource(dataSource);
        return sqlSessionFactoryBean.getObject();
    }


    @Bean(name = "tdengineSqlSessionTemplate")
    public SqlSessionTemplate tdengineSqlSessionTemplate(@Qualifier("tDengineSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    public Resource[] resolveMapperLocations(String[] mapperLocations) {
        ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
        List<Resource> resources = new ArrayList<Resource>();
        if (mapperLocations != null) {
            for (String mapperLocation : mapperLocations) {
                try {
                    Resource[] mappers = resourceResolver.getResources(mapperLocation);
                    resources.addAll(Arrays.asList(mappers));
                } catch (IOException e) {
                    // ignore
                }
            }
        }
        return resources.toArray(new Resource[resources.size()]);
    }



    /**
     * @return
     * @Method
     * @Description 根据数据库连接自动创建数据库
     * @Param null
     * @date 2022/5/24,0024 14:32
     * @author wxy
     */
    public void createDatabase() {
        try {
            String dbName = this.dbName;
            String jdbcUrl = this.jdbc;
            String username = this.username;
            String password = this.password;
            jdbcUrl += ("&user=" + username);
            jdbcUrl += ("&password=" + password);
            int startIndex = jdbcUrl.indexOf('/', 12);
            int endIndex = jdbcUrl.indexOf('?');
            String newJdbcUrl = jdbcUrl.substring(0, startIndex);
            newJdbcUrl = newJdbcUrl + jdbcUrl.substring(endIndex);
            System.out.println(newJdbcUrl);

            Properties connProps = new Properties();
            connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
            connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
            connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
            Connection conn = DriverManager.getConnection(newJdbcUrl, connProps);
            String csql = String.format(
                    "create database if not exists %s PRECISION '%s' KEEP %d DURATION %d BUFFER %d;",
                    dbName,
                    this.precision,
                    this.keep,
                    this.duration,
                    this.buffer
            );
            System.out.println(csql);
            conn.createStatement().execute(csql);
            conn.close();
            log.info("完成数据库创建");
        } catch (Exception e) {
            log.info("错误", e.getMessage());
            e.printStackTrace();
        }
    }


}
